using CfgTable;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using UnityEngine;
using UnityEngine.UI;

namespace IQIGame.Onigao.GamePlay
{
    public class UINLightDialogItem : UIBaseNode
    {

        #region Template Generate,don't modify
        protected partial class UIB_UINLightDialogItem
        {
            #region ObjectBinding Generate 
            public IQIGame.Onigao.Framework.ExText tex_Content { protected set; get; }
            public IQIGame.Onigao.Framework.ExImage image { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("tex_Content", out var __tbv0);
                this.tex_Content = __tbv0;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExImage>("image", out var __tbv1);
                this.image = __tbv1;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        /// <summary>
        /// 可以自定义修改的
        /// </summary>
        protected partial class UIB_UINLightDialogItem
        {
            public virtual void StartBinding(GameObject __go)
            {
                var binding = __go.GetComponent<ObjectBinding>();
                if (binding != null)
                {
                    this.InitBinding(binding);
                }
            }
        }
        protected UIB_UINLightDialogItem ui { get; set; }

        private const int MaxWidth = 450;
        private Transform _followTarget;
        private Vector3 _offsetWorld;
        private Vector2 _uiOffset;
        private ContentSizeFitter _contentSizeFitter;
        private TextGenerator _textGen;
        private TextGenerationSettings _textGenSetting;

        protected override void BeforeInit()
        {
            ui = new UIB_UINLightDialogItem();
            ui.StartBinding(gameObject);
        }

        protected override void OnInit()
        {
            _contentSizeFitter = gameObject.GetComponent<ContentSizeFitter>();
            _textGen = ui.tex_Content.cachedTextGenerator;
            _textGenSetting = ui.tex_Content.GetGenerationSettings(Vector2.zero);
            _textGenSetting.horizontalOverflow = HorizontalWrapMode.Overflow;
        }

        protected override void OnShow()
        {

        }

        protected override void OnHide()
        {
            ResetItem();
        }

        /// <summary>
        /// 开始气泡对话（通过CfgLevelEntityBubble指定参数）
        /// </summary>
        /// <param name="cfgBubble"></param>
        /// <param name="speakerName"></param>
        /// <returns></returns>
        public async UniTask StartDialog(CfgLevelEntityBubble cfgBubble, string speakerName)
        {
            bool isImageMode = !string.IsNullOrEmpty(cfgBubble.ImageContent);
            string showText = null;
            if (!isImageMode)
            {
                // 添加说话名字
                showText = cfgBubble.Desc;
                if (!string.IsNullOrEmpty(speakerName))
                {
                    showText = speakerName + "：" + showText;
                }
            }

            float lifeTime = cfgBubble.BubbleLifeTime.MillisecToSec();

            if (isImageMode)
            {
                await StartImageDialog(cfgBubble.ImageContent_fullPath, lifeTime);
            }
            else
            {
                await StartTextDialog(showText, cfgBubble.DisplaySpeed, lifeTime);
            }
        }

        /// <summary>
        /// 开始文本对话气泡
        /// </summary>
        /// <param name="text"></param>
        /// <param name="speed"></param>
        /// <param name="lifeTime"></param>
        /// <returns></returns>
        public async UniTask StartTextDialog(string text, float speed, float lifeTime)
        {
            SwitchToType(true);

            RefreshPositionAndSize();

            if (speed <= 1e-6)
            {
                //非打字机模式
                await TweenDialog(text, lifeTime);
            }
            else
            {
                await TweenDialogTypewriter(text, speed, lifeTime);
            }
        }

        /// <summary>
        /// 开始图片气泡对话
        /// </summary>
        /// <param name="path"></param>
        /// <param name="lifeTime"></param>
        /// <returns></returns>
        public async UniTask StartImageDialog(string path, float lifeTime)
        {
            SwitchToType(false);

            SetImageSprite(this.ui.image, path);

            RefreshPositionAndSize();

            //创建Tween
            await DOTween.Sequence().SetLink(this.gameObject).SetTarget(this.ui.image)
            .AppendInterval(lifeTime)
            .OnUpdate(OnUpdate)
            .AwaitForComplete();
        }

        private void SwitchToType(bool isText)
        {
            this.ui.tex_Content.text = string.Empty;
            _contentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;

            this.ui.tex_Content.DOKill();
            this.ui.image.DOKill();

            this.ui.tex_Content.SetActive(isText);
            this.ui.image.SetActive(!isText);
        }

        private async UniTask TweenDialog(string text, float lifeTime)
        {
            ui.tex_Content.text = text;
            //创建Tween
            await DOTween.Sequence().SetLink(this.gameObject).SetTarget(this.ui.tex_Content)
            .AppendInterval(lifeTime)
            .OnUpdate(OnUpdate)
            .AwaitForComplete();
        }

        private async UniTask TweenDialogTypewriter(string text, float speed, float lifeTime)
        {
            float duration = text.Length / speed;
            float delayAfterTypeDuration = lifeTime - duration;
            if (delayAfterTypeDuration < 0)
            {
                delayAfterTypeDuration = 0;
            }

            //创建Tween
            await DOTween.Sequence().SetLink(this.gameObject).SetTarget(this.ui.tex_Content)
            .Append(this.ui.tex_Content.DOText(text, duration).SetEase(Ease.Linear))
            .AppendInterval(lifeTime)
            .OnUpdate(OnUpdate)
            .AwaitForComplete();
        }

        public void SetFllowTarget(Transform follow, Vector3 offsetWorld, Vector2 uiOffset)
        {
            this._followTarget = follow;
            this._offsetWorld = offsetWorld;
            this._uiOffset = uiOffset;
        }

        protected void RefreshPositionAndSize()
        {
            if (this._followTarget == null)
            {
                return;
            }
            //刷新位置
            Vector2 anchorPos = ManagerCenter.UI.World2UIPosition(this._followTarget.position + this._offsetWorld, out var inCamBack);
            this.transform.anchoredPosition = anchorPos + _uiOffset;

            //有文本需要刷新排版模式，否则不用
            if (!string.IsNullOrEmpty(ui.tex_Content.text))
            {
                var width = _textGen.GetPreferredWidth(ui.tex_Content.text, _textGenSetting);
                var trans = this.gameObject.transform as RectTransform;
                if (width >= MaxWidth && trans.sizeDelta.x != MaxWidth)
                {
                    var sizeDelta = trans.sizeDelta;
                    sizeDelta.x = MaxWidth;
                    trans.sizeDelta = sizeDelta;

                    _contentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
                }
                else if (width < MaxWidth)
                {
                    _contentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
                }
            }
        }

        public void ResetItem()
        {
            this.ui.tex_Content.DOKill();
            this.ui.image.DOKill();
            this._followTarget = null;
            this._offsetWorld = default;
            this._uiOffset = default;
        }

        public void OnUpdate()
        {
            RefreshPositionAndSize();
        }

        protected override void OnDispose()
        {
            _contentSizeFitter = null;
            _textGen = null;
        }
    }
}
